package com.uobgroup.ews.uam.core.validator;

import java.lang.reflect.Field;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.apache.log4j.Logger;

/**
 * Utility class for validating the JPA Entities using the Reflection APIs
 * @author ndduy
 *
 */
public class JpaEntityValidator {

   private static Logger logger = Logger.getLogger(JpaEntityValidator.class);
   
   /**
    * Check if the field value violated the {@link NotNull} constraint defined in the annotation
    * @author ndduy
    * @param entity {@link Object}
    * @param fieldName {@link String}
    * @param ignoreEmptyString {@link Boolean} just meaningful when the field type is {@link String}
    * @return {@link Boolean}
    */
   public static boolean isNullConstraintViolated(Object entity, String fieldName, boolean excludeEmptyString){
      try {
         Field field = entity.getClass().getDeclaredField(fieldName);
         if(field != null){
            field.setAccessible(true);
            if(field.getName().equals(fieldName)){
               if(field.getAnnotation(NotNull.class) != null){
                  Object value = field.get(entity);
                  if(field.getType().equals(String.class)){
                     if(excludeEmptyString){
                        return value == null;
                     } else{
                        String valueStr = (String)value;
                        return valueStr == null || valueStr.trim().length() == 0;
                     }
                  } else{
                     return value == null;
                  }
               }
            }
         }
      }
      catch (IllegalArgumentException e) {
         logger.error(e.getMessage());
      }
      catch (IllegalAccessException e) {
         logger.error(e.getMessage());
      }
      catch (SecurityException e) {
         logger.error(e.getMessage());
      }
      catch (NoSuchFieldException e) {
         logger.error(e.getMessage());
      }
      
      return false;
   }
   
   /**
    * Check if the length of the field exceeded the max length defined in the annotation
    * @author ndduy
    * @param entity {@link Object}
    * @param fieldName {@link String}
    * @return {@link Boolean}
    */
   public static boolean isMaxLengthExceeded(Object entity, String fieldName){
      try {
         Field field = entity.getClass().getDeclaredField(fieldName);
         if(field != null){
            field.setAccessible(true);
            if(field.getName().equals(fieldName)){
               if(field.getType().equals(String.class)
                     && field.getAnnotation(Size.class) != null){
                  String value = (String)field.get(entity);
                  if(value != null && value.length() > field.getAnnotation(Size.class).max()){
                     return true;
                  }
               }
            }
         }
      }
      catch (IllegalArgumentException e) {
         logger.error(e.getMessage());
      }
      catch (IllegalAccessException e) {
         logger.error(e.getMessage());
      }
      catch (SecurityException e) {
         logger.error(e.getMessage());
      }
      catch (NoSuchFieldException e) {
         logger.error(e.getMessage());
      }
      return false;
   }
}
